/**
* @file BigInteger.cpp in Leetcode
* @author rebeater
* @comment 大整数的运算
* Create on 8/14/21 6:02 PM
* @version 1.0
**/


#include "BigInteger.h"
#include <iostream>
#include <cmath>
BigInteger::BigInteger() {
  data.clear();
  positive = true;
}
BigInteger::BigInteger(int d) {
  data.clear();
  if (d >= 0) {
	positive = true;
	data.push_back(d);
	arrange();
  } else {
	positive = false;
	data.push_back(d);
	arrange();
  }
//  for (auto s:data) cout << s << '\t';
}
BigInteger operator+(const BigInteger &a, int b) {
  auto res = BigInteger();
  res.data = a.data;
  res.data[0] += b;
  res.arrange();
  return res;
}

istream &operator>>(istream &is, BigInteger &bi) {
  /** TODO 这个功能没做好*/
  bi.data.clear();
  char c;
  char a;
  int b;
  is >> c;
  if (c == '-') {
	bi.positive = false;
  } else {
	bi.positive = true;
  }
  do {
	is >> a;
	b = static_cast<int>(a - 0x30);
	if (0 <= b and b < 10) {
	  bi.data.push_back(b);
	} else {
	  break;
	}
  } while (is.good());
  bi.arrange();
  return is;
}
/**
 * 输出流
 * @param os
 * @param bi
 * @return
 */
ostream &operator<<(ostream &os, BigInteger &bi) {
  if (!bi.IsPositive()) {
	os << "-";
	os << -bi;
	return os;
  }
  if (bi.Length() == 0) {
	os << 0;
	return os;
  };
  int i = bi.data.size() - 1;
  os << bi.data[i];
  i--;
  while (i >= 0) {
	if ((i + 1) % 4 == 0) {
	  cout << ",";
	}
	os << bi.data[i];
	i--;
  }
  return os;
}
BigInteger operator+(const BigInteger &a, const BigInteger &b) {
  auto res = BigInteger();
  int i = 0;
  int len1 = a.Length(), len2 = b.Length();
  int min_len = len1 < len2 ? len1 : len2;
  while (i < min_len) {
	res.data.push_back(a.data[i] + b.data[i]);
	i++;
  }
  while (i < len2) { res.data.push_back(b.data[i]), i++; }
  while (i < len1) { res.data.push_back(a.data[i]), i++; }
  res.arrange();
  return res;
}
int BigInteger::Length() const {
  return data.size();
}
void BigInteger::arrange() {
  int carry = 0;
  int i = 0;
  if (data.empty()) return;
  do {
	data[i] += carry;
	if (data[i] >= BigInteger::numeration) {
	  carry = data[i] / BigInteger::numeration;
	  data[i] %= BigInteger::numeration;
	} else {
	  carry = 0;
	}
	if (data[i] < 0) {
	  carry = data[i] / numeration - 1;
	  data[i] -= numeration * carry;
/*	  carry = (-data[i])/numeration;
	  data[i] %= numeration;*/
	}
	i++;
  } while (i < data.size());/*i */

  if (carry > 0) {/*多出一位来*/
	positive = true;
	do {
	  data.push_back(carry % BigInteger::numeration);
	  carry = carry / BigInteger::numeration;
	} while (carry > 0);
  }
  /*负数规整*/
  if (carry < 0) {
	positive = false;
	while (carry < -1) {
	  data.push_back((-carry / (numeration) + 1) * numeration + carry);
//	  if(carry < -numeration)
	  carry = carry / (numeration) - 1;
	}
	data.push_back(carry);
  }
/*去掉末尾的0*/
  for (int i = data.size(); i > 0; i--) {
	if (data[i - 1] == 0) {
	  data.pop_back();
	} else {
	  break;
	}
  }
}
BigInteger operator*(const BigInteger &a, int b) {
  auto res = BigInteger();
  res.data = a.data;
  int len = a.Length();
  for (int i = 0; i < len; i++) {
	res.data[i] *= b;
  }
  res.arrange();
  return res;
}
BigInteger operator*(const BigInteger &a, const BigInteger &b) {
  auto res = BigInteger();
  for (int j = b.Length() - 1; j >= 0; j--) {
	res *= BigInteger::numeration;
	res += a * b.data[j];
  }
//  res.arrange();
  if (a.IsPositive() != b.IsPositive()) {
/*	负数的存储方式不一样*/
	res.positive = false;
	for (auto &d:res.data)d = -d;
	res.arrange();
  };

  return res;
}
BigInteger operator+=(BigInteger &a, int b) {
  a.data[0] += b;
  a.arrange();
  return a;
}
BigInteger operator+=(BigInteger &a, const BigInteger &b) {
  auto res = BigInteger();
  int i = 0;
  int len1 = a.Length(), len2 = b.Length();
  int min_len = len1 < len2 ? len1 : len2;
  while (i < min_len) {
	a.data[i] += b.data[i];
	i++;
  }
  while (i < len2) { a.data.push_back(b.data[i]), i++; }
  a.arrange();
  return res;
}
BigInteger operator*=(BigInteger &a, int b) {
  int len = a.Length();
  for (int i = 0; i < len; i++) {
	a.data[i] *= b;
  }
  a.arrange();
  return a;
}
BigInteger operator*=(BigInteger &a, const BigInteger &b) {
  return BigInteger();
}
BigInteger::operator int() {
  int sum = 0;
  for (int i = (int)data.size() - 1; i >= 0; i--) {
	sum *= numeration;
	sum += data[i];
  }
  return sum;
}
bool BigInteger::IsPositive() const {
  return positive;
}
BigInteger operator-(const BigInteger &a) {
  auto res = a;
  for (int i = 0; i < a.Length(); i++) {
	res.data[i] = -a.data[i];
  };
  res.positive = !res.positive;
  res.arrange();
  return res;
}
BigInteger operator-(const BigInteger &a, int b) {
  return a + (-b);
}
BigInteger operator-(const BigInteger &a, const BigInteger &b) {
  return a + (-b);
}
BigInteger operator-=(BigInteger &a, const BigInteger &b) {
  a = a - b;
  return a;
}
BigInteger operator-=(BigInteger &a, const int b) {
  a = a - b;
  return a;
}
BigInteger::BigInteger(long long int d) {
  data.clear();
  positive = d > 0;
  while (d) {
	data.push_back(d % numeration);
	d /= numeration;
  }
  arrange();
}

void test() {

/*  BigInteger a(-2135);
  BigInteger b(2135);
  cout<<a.Length()<<endl;
  a += 2135;
  cout<<a<<endl;
  cout<<a.Length();
  */
  BigInteger a = BigInteger(123);
  BigInteger b = BigInteger(-45);
  BigInteger c = a * 9;

  cout << "a =" << a << endl;
  cout << "b =" << b << endl;

  cout << "a * 9 = " << c << endl;
  a += 9;

  cout << "a += 9, a = " << a << endl;
  a += b;

  cout << "a += b, a = " << a << endl;
  a *= 9;
  cout << "a *= 9,a=" << a << endl;

  int ai = int(a);
  int bi = int(b);
  cout << "a =" << a << endl;
  cout << "b =" << b << endl;

  cout << "a + b =" << a + b << endl;
  cout << "ai + bi =" << ai + bi << endl;

  cout << "a * b =" << (a * a * b * b * b * b) << endl;
  cout << "ai * bi =" << (1.0 * ai * ai * bi * bi * bi * bi) << endl;

  a = 677;
  b = {-677};
  a.arrange();
  c = -b;
  cout << "a = " << a << endl;
  cout << "b = " << b << endl;
  cout << "c = " << c << endl;
  auto d = a + 1354;
  cout << "a-b = " << (a + 1354) << endl;
  cout << "a - b * 2 = " << a - b * 2 << endl;
  cout << "a - b * 4 =" << a - b * 4 << endl;
}

#include <bits/stdc++.h>

int main(int argc, char *argv[]) {
  BigInteger c{4206347770389810LL};

  auto a = BigInteger(-53528010);
  auto b = BigInteger(78582181);
  cout << c << endl;
  auto d = a * b;
  cout << d << endl;
  cout << -d << endl;
  cout << -(-d) << endl;
  cout << -(-(-d)) << endl;

//  return -0;
  ifstream is(argv[1]);
  string linebuffer;
  int ai, bi;
  string di;
  BigInteger res;
  char ci;
  while (is.good() and !is.eof()) {
	getline(is, linebuffer);
	stringstream ss(linebuffer);
	ss >> ai >> ci >> bi >> di;
	BigInteger a{ai}, b{bi}, d{ci};
	switch (ci) {
	  case '+': res = a + b;
		break;
	  case '-': res = a - b;
		break;
	  case '*': res = a * b;
		break;
	  case '/': res = a / b;
		break;
	  default: cout << "error: not supported operator" << endl;
		continue;
	}
	cout << a << ' ' << ci << ' ' << bi << " = " << di << " == " << res << endl;
  }

}
